#pragma once
#include "interfaces.h"
#include "AssetData.h"
#include "LevelData.h"
#include "RenderData.h"
#include "TransformData.h"
#include "Texture.h"
#include <irrXML.h>

class FileReadCallback : public irr::io::IFileReadCallBack
{
public:

	char * bfr; int sze;
	virtual int read(void* buffer, int sizeToRead){
		memcpy(buffer, bfr, sze);
		return sze;
	}
	virtual int getSize() { return sze; }
};
class RELevelParser : public IAssetParser
{
public:
	RELevelParser();
	~RELevelParser() {}

	FileReadCallback m_FileReadCallback;
	AssetDataPtr  m_pAssetData;
	AssetDataList m_AssetDataList;
	ParserStack Stack;
	D3DXVECTOR3 m_TempVec; // temp vector for data
	irr::io::IrrXMLReader* xml;

	virtual AssetDataList & VLoad(Resource & res, char * bfr, unsigned int sze );
	virtual AssetDataList & VGetData();
	virtual void VBegin();
	virtual void VEnd();


	//Logical functions
	static void STACK_END(RELevelParser* instance);
	static void STACK_BEGIN(RELevelParser *instance);
	static void RESOURCE_FILE(RELevelParser *instance);
	static void COMPONENT(RELevelParser* instance);

	//level. tells when a RE_NEW level starts(one file can store more than one level)
	static void LEVEL(RELevelParser* instance);
		//actor. called when a RE_NEW actor is introduced. This does not require level. Each actor can have a file, and the level would just reference them
		static void ACTOR(RELevelParser* instance);
			//transform. called when a RE_NEW transform component is introduced. Again it can have separeate file and would be accessed by ref
			static void TRANSFORM(RELevelParser* instance);
				//when position of transform cmp is introduced
				static void POSITION(RELevelParser* instance);
					static void POSITION_X(RELevelParser* instance);
					static void POSITION_Y(RELevelParser* instance);
					static void POSITION_Z(RELevelParser* instance);
				//when rotation of transform cmp is introduced
				static void ROTATION(RELevelParser* instance);
					static void ROTATION_X(RELevelParser* instance);
					static void ROTATION_Y(RELevelParser* instance);
					static void ROTATION_Z(RELevelParser* instance);
				//when scale of transform cmp is introduced
				static void SCALE(RELevelParser* instance);
					static void SCALE_X(RELevelParser* instance);
					static void SCALE_Y(RELevelParser* instance);
					static void SCALE_Z(RELevelParser* instance);
			//render. Called when RE_NEW render component
			static void RENDER(RELevelParser* instance);
				//mesh. A RE_NEW mesh. One render component may have no mroe than 1 mesh component, however mesh cmp may have child meshes which would also be rendered
				static void MESH(RELevelParser* instance);
					static void MATERIAL(RELevelParser* instance);
						static void AMBIENT(RELevelParser* instance);
							static void AMBIENT_A(RELevelParser* instance);
							static void AMBIENT_R(RELevelParser* instance);
							static void AMBIENT_G(RELevelParser* instance);
							static void AMBIENT_B(RELevelParser* instance);
						static void DIFFUSE(RELevelParser* instance);
							static void DIFFUSE_A(RELevelParser* instance);
							static void DIFFUSE_R(RELevelParser* instance);
							static void DIFFUSE_G(RELevelParser* instance);
							static void DIFFUSE_B(RELevelParser* instance);
						static void SPECULAR(RELevelParser* instance);
							static void SPECULAR_A(RELevelParser* instance);
							static void SPECULAR_R(RELevelParser* instance);
							static void SPECULAR_G(RELevelParser* instance);
							static void SPECULAR_B(RELevelParser* instance);
							static void SPECULAR_P(RELevelParser* instance);
						static void TEXTURE(RELevelParser* instance);
};